#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     json_response
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/7/15
-------------------------------------------------
   修改描述-2021/7/15:
-------------------------------------------------
"""

from typing import Any, Dict, Optional

# 自定义返回的错误的响应体信息
# ORJSONResponse一依赖于：orjson
from fastapi.responses import ORJSONResponse

import time
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from afast_core.core_tools import json_helper


class ApiResponse(ORJSONResponse):
    # 定义返回响应码--如果不指定的话则默认都是返回200
    http_status_code = 200
    # 默认成功
    api_code = 200
    # 默认Node.如果是必选的，去掉默认值即可
    data: Optional[Dict[str, Any]] = []  # 结果可以是{} 或 []
    # message = '成功'
    result: Optional[Dict[str, Any]] = None  # 结果可以是{} 或 []
    message = '成功'
    success = True
    timestamp = int(time.time() * 1000)

    def __init__(self, success=None, http_status_code=None, api_code=None, data=None, message=None, **options):
        self.message = message or self.message
        self.api_code = api_code or self.api_code
        self.http_status_code = http_status_code or self.http_status_code
        self.data =data if data is not None else self.data
        self.success = success or self.success

        # 返回内容体
        if isinstance(self.data, BaseModel):
            self.result = self.data.dict()
        # 返回内容体
        body = dict(
            msg=self.message,
            code=self.api_code,
            data=self.data,
            ok=self.success,
            level=None,
            timestamp=self.timestamp
        )
        # 如果是直接的输出查询的模型结果需要通过jsonable_encoder转化处理
        # jsonable_encoder 处理不同字符串返回  比如时间戳 datatime类型的处理
        # jsonable_encoder(body)
        super(ApiResponse, self).__init__(status_code=self.http_status_code, content=jsonable_encoder(body), **options)


class SnowyBadrequestException(ApiResponse):
    http_status_code = 400
    api_code = 10031
    data = None  # 结果可以是{} 或 []
    message = '错误的请求'
    success = False

class SnowyBusinessExceptionResponse(ApiResponse):
    http_status_code = 400
    api_code = 10031
    data = None  # 结果可以是{} 或 []
    message = '错误的请求'
    success =False

class SnowyLimiterResException(ApiResponse):
    http_status_code = 429
    api_code = 429
    data = None  # 结果可以是{} 或 []
    message = '访问的速度过快'
    success = False

class SnowySuccess(ApiResponse):
    http_status_code = 200
    api_code = 0
    data = None  # 结果可以是{} 或 []
    message = 'success'
    success = True


class SnowyFail(ApiResponse):
    http_status_code = 200
    api_code = -1
    data = None  # 结果可以是{} 或 []
    message = '处理失败'
    success = False


class SnowyParameterException(ApiResponse):
    http_status_code = 200
    data = None  # 结果可以是{} 或 []
    message = '参数校验错误,请检查提交的参数信息'
    api_code = 30001
    success = False

class SnowyCircuitBreakerOpenException(ApiResponse):
    http_status_code = 200
    data = None  # 结果可以是{} 或 []
    message = '系统负载过高'
    api_code = 1000
    success = False


class SnowyValueErrorException(ApiResponse):
    http_status_code = 200
    data = None  # 结果可以是{} 或 []
    message = 'ValueError响应报文信息错误'
    api_code = 1000
    success = False


class SnowyUnauthorizedException(ApiResponse):
    http_status_code = 200
    data = None  # 结果可以是{} 或 []
    message = '未经许可授权'
    api_code = 1032
    success = False


class SnowyArithmeticErrorException(ApiResponse):
    http_status_code = 200
    data = None  # 结果可以是{} 或 []
    message = '逻辑运算过程出现错误'
    api_code = 1033
    success = False


class SnowyForbiddenException(ApiResponse):
    http_status_code = 403
    data = None  # 结果可以是{} 或 []
    message = '失败！当前访问没有权限，或操作的数据没权限!'
    api_code = 10034
    success = False


class SnowyNotfoundException(ApiResponse):
    http_status_code = 404
    data = None  # 结果可以是{} 或 []
    message = '访问地址不存在'
    api_code = 10035
    success = False



class SnowyMethodnotallowedException(ApiResponse):
    http_status_code = 405
    data = None  # 结果可以是{} 或 []
    message = '不允许使用此方法提交访问'
    api_code = 10036
    success = False


class SnowyOtherException(ApiResponse):
    http_status_code = 800
    data = None  # 结果可以是{} 或 []
    message = '未知的其他HTTPEOOER异常'
    api_code = 10037
    success = False


class SnowyInternalErrorException(ApiResponse):
    http_status_code = 500
    data = None  # 结果可以是{} 或 []
    message = '程序员哥哥睡眠不足，系统崩溃了！'
    api_code = 500
    success = False


class SnowyInvalidTokenException(ApiResponse):
    http_status_code = 401
    api_code = 401
    data = None  # 结果可以是{} 或 []
    message = '很久没操作，令牌失效'
    success = False


class SnowyExpiredTokenException(ApiResponse):
    http_status_code = 422
    data = None  # 结果可以是{} 或 []
    message = '很久没操作，令牌过期'
    api_code = 10050
    success = False


class SnowyFileTooLargeException(ApiResponse):
    http_status_code = 413
    api_code = 413
    data = None  # 结果可以是{} 或 []
    message = '文件体积过大'
    success = False


class FileTooManyException(ApiResponse):
    http_status_code = 413
    message = '文件数量过多'
    api_code = 10120
    data = None  # 结果可以是{} 或 []
    success = False


class FileExtensionException(ApiResponse):
    http_status_code = 401
    message = '文件扩展名不符合规范'
    api_code = 10121
    data = None  # 结果可以是{} 或 []
    success = False


# @Getter
# @AllArgsConstructor
# public enum UnexpectedErrorCode implements ErrorCode {
#     BUSINESS_HANDING(20001, "呃~ 业务繁忙，请稍后重试"),
#     PAY_ORDER_ID_ERROR(20002, "付款单id发生了异常，请联系技术人员排查");
#
#     private final int code;
#     private final String msg;
#     private final String level;
#
#     UnexpectedErrorCode(int code, String msg) {
#         this.code = code;
#         this.msg = msg;
#         this.level = LEVEL_UNEXPECTED;
#     }
# }
# UserErrorCode
#
# @Getter
# @AllArgsConstructor
# public enum UserErrorCode implements ErrorCode {
#
#     PARAM_ERROR(30001, "参数错误"),
#     DATA_NOT_EXIST(30002, "左翻右翻，数据竟然找不到了~"),
#     ALREADY_EXIST(30003, "数据已存在了呀~"),
#     REPEAT_SUBMIT(30004, "亲~您操作的太快了，请稍等下再操作~"),
#     NO_PERMISSION(30005, "对不起，您无法访问此资源哦~"),
#     LOGIN_STATE_INVALID(30007, "您还未登录或登录失效，请重新登录！"),
#     FORM_REPEAT_SUBMIT(30009, "请勿重复提交");